Header file boolean.hpp

namespace type_safe
{
    class boolean;
    
    constexpr bool operator==(const boolean& a, const boolean& b) noexcept;
    template <typename T>
    constexpr bool operator==(const boolean& a, T b) noexcept;
    template <typename T>
    constexpr bool operator==(T a, const boolean& b) noexcept;
    
    constexpr bool operator!=(const boolean& a, const boolean& b) noexcept;
    template <typename T>
    constexpr bool operator!=(const boolean& a, T b) noexcept;
    template <typename T>
    constexpr bool operator!=(T a, const boolean& b) noexcept;
    
    //=== Input/output ===//
    template <typename Char, class CharTraits>
    std::basic_istream<Char, CharTraits>& operator>>(std::basic_istream<Char, CharTraits>& in, boolean& b);
    
    template <typename Char, class CharTraits>
    std::basic_ostream<Char, CharTraits>& operator<<(std::basic_ostream<Char, CharTraits>& out, const boolean& b);
    
    //=== Comparison function objects ===//
    struct equal_to;
    struct not_equal_to;
    struct less;
    struct less_equal;
    struct greater;
    struct greater_equal;
}

namespace std
{
}

Class type_safe::boolean [types]

class boolean
{
public:
    boolean() = delete;
    
    template <typename T, typename = detail::enable_boolean<T>>
    constexpr boolean(T value) noexcept;
    
    template <typename T, typename = detail::enable_boolean<T>>
    boolean& operator=(T value) noexcept;
    
    constexpr operator bool() const noexcept;
    
    constexpr boolean operator!() const noexcept;
};

A type safe boolean class.

It is a tiny, no overhead wrapper over bool. It can only be constructed from bool values and does not implicitly convert to integral types.

Function template type_safe::boolean::boolean

template <typename T, typename = detail::enable_boolean<T>>
constexpr boolean(T value) noexcept;

Effects: Creates a boolean from the given value.

Notes: This function does not participate in overload resolution if T is not a boolean type. \param 1 \exclude

Assignment operator type_safe::boolean::operator=

template <typename T, typename = detail::enable_boolean<T>>
boolean& operator=(T value) noexcept;

Effects: Assigns the given value to the boolean.

Notes: This function does not participate in overload resolution if T is not a boolean type. \param 1 \exclude

Conversion operator type_safe::boolean::operator bool

constexpr operator bool() const noexcept;

Returns: The stored bool value.

Operator type_safe::boolean::operator!

constexpr boolean operator!() const noexcept;

Returns: The same as !static_cast<bool>(*this).


Comparison operator type_safe::operator== [types]

(1)  constexpr bool operator==(const boolean& a, const boolean& b) noexcept;

(2)  template <typename T>
     constexpr bool operator==(const boolean& a, T b) noexcept;

(3)  template <typename T>
     constexpr bool operator==(T a, const boolean& b) noexcept;

ts::boolean equality comparison.

Returns: true if (1) both ts::boolean objects have the same value, (2)/(3) the boolean has the same value as the given value, false otherwise.

Notes: (2)/(3) do not participate in overload resolution if T is not a boolean type.

Comparison operator type_safe::operator!= [types]

(1)  constexpr bool operator!=(const boolean& a, const boolean& b) noexcept;

(2)  template <typename T>
     constexpr bool operator!=(const boolean& a, T b) noexcept;

(3)  template <typename T>
     constexpr bool operator!=(T a, const boolean& b) noexcept;

ts::boolean in-equality comparison.

Returns: false if (1) both ts::boolean objects have the same value, (2)/(3) the boolean has the same value as the given value, true otherwise.

Notes: (2)/(3) do not participate in overload resolution if T is not a boolean type.

Input operator type_safe::operator>> [types]

template <typename Char, class CharTraits>
std::basic_istream<Char, CharTraits>& operator>>(std::basic_istream<Char, CharTraits>& in, boolean& b);

ts::boolean input operator.

Effects: Reads a bool from the std::istream and assigns it to the given ts::boolean.

Output operator type_safe::operator<< [types]

template <typename Char, class CharTraits>
std::basic_ostream<Char, CharTraits>& operator<<(std::basic_ostream<Char, CharTraits>& out, const boolean& b);

ts::boolean output operator.

Effects: Converts the given ts::boolean to bool and writes it to the std::ostream.

Comparison function objects [types]

(1)  struct equal_to
     {
         using is_transparent = int;
         
         template <typename T1, typename T2>
         constexpr bool operator()(T1&& a, T2&& b) const noexcept('hidden');
     };

(2)  struct not_equal_to
     {
         using is_transparent = int;
         
         template <typename T1, typename T2>
         constexpr bool operator()(T1&& a, T2&& b) const noexcept('hidden');
     };

(3)  struct less
     {
         using is_transparent = int;
         
         template <typename T1, typename T2>
         constexpr bool operator()(T1&& a, T2&& b) const noexcept('hidden');
     };

(4)  struct less_equal
     {
         using is_transparent = int;
         
         template <typename T1, typename T2>
         constexpr bool operator()(T1&& a, T2&& b) const noexcept('hidden');
     };

(5)  struct greater
     {
         using is_transparent = int;
         
         template <typename T1, typename T2>
         constexpr bool operator()(T1&& a, T2&& b) const noexcept('hidden');
     };

(6)  struct greater_equal
     {
         using is_transparent = int;
         
         template <typename T1, typename T2>
         constexpr bool operator()(T1&& a, T2&& b) const noexcept('hidden');
     };

Comparison functors similar to the std:: version, but explicitly cast the result of the comparison to bool.

This allows using types where the comparison operator returns ts::boolean, as it can not be implicitly converted to bool so, for example, std::less can not be used.

Notes: These comparison functors are always transparent, i.e. can be used with two different types.